import { Injectable, NestMiddleware } from '@nestjs/common';
import { Request, Response, NextFunction } from 'express';
import { AuthService } from '../auth.service';
import { JwtService } from '@nestjs/jwt';
import { ConfigService } from '@nestjs/config';
import { JwtStrategys } from '../strategies/jwt.strategy';

@Injectable()
export class TokenRefreshMiddleware implements NestMiddleware {
  constructor(
    private authService: AuthService,
    private jwtService: JwtService,
    private configService: ConfigService
  ) {}

  async use(req: Request, res: Response, next: NextFunction) {
    const authHeader = req.headers.authorization;
    
    if (!authHeader || !authHeader.startsWith('Bearer ')) {
      return next();
    }

    const token = authHeader.substring(7);
    
    try {
      // 解码token获取过期时间
      const decoded = this.jwtService.decode(token) as any;
      
      if (!decoded || !decoded.exp) {
        return next();
      }

      const currentTime = Math.floor(Date.now() / 1000);
      const timeUntilExpiry = decoded.exp - currentTime;
      
      // 在响应头中添加token过期时间信息，供客户端判断
      if (timeUntilExpiry > 0) {
        res.setHeader('X-Token-Expires-In', timeUntilExpiry.toString());
        
        // 如果token在5分钟内过期，添加即将过期的提示
        if (timeUntilExpiry < 300) { // 300秒 = 5分钟
          res.setHeader('X-Token-Expiring-Soon', 'true');
        }
      }
      
      // 检查客户端是否主动请求刷新token
      const refreshToken = req.headers['x-refresh-token'] as string;
      
      if (refreshToken) {
        // 客户端主动请求刷新token
        const strategyName = this.determineStrategy(req);
        
        const newTokenPair = await this.authService.refreshToken(refreshToken, strategyName);
        
        if (newTokenPair) {
          // 在响应头中返回新的token
          res.setHeader('X-New-Access-Token', newTokenPair.access_token);
          res.setHeader('X-New-Refresh-Token', newTokenPair.refresh_token);
          res.setHeader('X-Token-Refreshed', 'true');
          
          // 更新请求头中的token，以便后续中间件使用新token
          req.headers.authorization = `Bearer ${newTokenPair.access_token}`;
        } else {
          // 刷新失败，添加错误提示
          res.setHeader('X-Token-Refresh-Failed', 'true');
        }
      }
    } catch (error) {
      // 忽略解码错误，让后续的验证中间件处理
    }

    next();
  }

  private determineStrategy(req: Request): keyof typeof JwtStrategys {
    // 根据请求路径或其他条件确定使用哪个JWT策略
    const path = req.path;
    
    if (path.startsWith('/admin')) {
      return 'admin';
    }
    
    return 'app';
  }
}
